#include "Game.h"

Game::Game()
{
	m_bRunning = false;
	m_nextBlockPos = Vec2(2, 2);
	m_state = GAME_OVER;
	m_bMusic = true;
	
}

Game::~Game()
{
	SAFE_DELETE(m_gameOverLayer);

	m_audio->StopAll();
	SAFE_DELETE(m_FXdeleteLine);
	SAFE_DELETE(m_FXgameOver);
	SAFE_DELETE(m_FXnewLevel);
	SAFE_DELETE(m_FXjump);
	SAFE_DELETE(m_FXrotate);
	SAFE_DELETE(m_music);

	SAFE_DELETE(m_block);
	SAFE_DELETE(m_nextBlock);
	SAFE_RELEASE(m_font);
	SAFE_DELETE(m_input);
	SAFE_DELETE(m_audio);
	SAFE_DELETE(m_sprite);
	SAFE_DELETE(m_background);
	SAFE_DELETE(m_inactiveSprite);
	SAFE_RELEASE(m_spriteHandler);
	SAFE_RELEASE(m_backbuffer);
	SAFE_RELEASE(m_device);
	SAFE_RELEASE(m_d3d);
}

bool Game::Preload()
{
	if(!LoadGame("Media/GameIni.xml"))
		return false;

	m_cellWidth = m_fieldSize.x / m_fieldWidth;
	m_cellHeight = m_fieldSize.y / m_fieldHeight; 

	return true;
}

bool Game::Init(HWND hWnd)
{
	m_hWnd = hWnd;

	if(!InitD3D())
		return false;

	m_audio = new Audio();
	if (!m_audio->Init())
		return false;

	m_FXdeleteLine = m_audio->Load("Media/deleteline.wav");
	m_FXrotate = m_audio->Load("Media/rotate.wav");
	m_FXjump = m_audio->Load("Media/jump.wav");
	m_FXnewLevel = m_audio->Load("Media/new level.wav");
	m_FXgameOver = m_audio->Load("Media/over.wav");
	m_music = m_audio->LoadStream("Media/background.ogg");
	m_audio->Play(m_music);
	m_music->channel->setVolume(0.2);
	

	srand ( time(NULL) );
	m_input = new CInput(m_hWnd);

	m_sprite = new CSprite();
	std::shared_ptr<CTexture> texture(new CTexture());
	if(!texture->Load("Media/fieldBg.png", m_device))
		return false;

	m_sprite->setImage(texture);
	float xscale = (float)(m_fieldSize.x + 20)/m_sprite->getWidth();
	float yscale = (float)(m_fieldSize.y)/m_sprite->getHeight();
	m_sprite->setScale(D3DXVECTOR3(xscale, yscale, 0));
	m_sprite->setPosition(D3DXVECTOR3(m_fieldPosition.x, m_fieldPosition.y, 0));

	m_inactiveSprite = new CSprite();
	std::shared_ptr<CTexture> texture2(new CTexture());
	if(!texture2->Load("Media/block8.png", m_device))
		return false;

	m_inactiveSprite->setImage(texture2);
	xscale = (float)m_cellWidth/m_inactiveSprite->getWidth();
	yscale = (float)m_cellHeight/m_inactiveSprite->getHeight();
	m_inactiveSprite->setScale(D3DXVECTOR3(xscale, yscale, 0));

	m_background = new CSprite();
	std::shared_ptr<CTexture> texture3(new CTexture());
	if(!texture3->Load("Media/background.png", m_device))
		return false;

	m_background->setImage(texture3);
	xscale = (float)SCREENWIDTH/m_background->getWidth();
	yscale = (float)SCREENHEIGHT/m_background->getHeight();
	m_background->setScale(D3DXVECTOR3(xscale, yscale, 0));

	m_gameOverLayer = new CSprite();
	std::shared_ptr<CTexture> texture4(new CTexture());
	if(!texture4->Load("Media/over.png", m_device))
		return false;

	m_gameOverLayer->setImage(texture4);
	xscale = (float)m_fieldSize.x/m_gameOverLayer->getWidth();
	yscale = (float)m_fieldSize.y/m_gameOverLayer->getHeight();
	m_gameOverLayer->setScale(D3DXVECTOR3(xscale, yscale, 0));
	m_gameOverLayer->setPosition(D3DXVECTOR3(m_fieldPosition.x, m_fieldPosition.y, 0));


	D3DXFONT_DESC fontDesc;
	fontDesc.Height          = 40;
	fontDesc.Width           = 0;
	fontDesc.Weight          = 0;
	fontDesc.MipLevels       = 1;
	fontDesc.Italic          = false;
	fontDesc.CharSet         = DEFAULT_CHARSET;
	fontDesc.OutputPrecision = OUT_DEFAULT_PRECIS;
	fontDesc.Quality         = DEFAULT_QUALITY;
	fontDesc.PitchAndFamily  = DEFAULT_PITCH | FF_DONTCARE;
	strcpy(fontDesc.FaceName, ("Times New Roman"));
	HR(D3DXCreateFontIndirect(m_device, &fontDesc, &m_font));

	if(!LoadBlockTypes("Media/BlockTypes.xml"))
		return false;

	m_field.resize(m_fieldHeight);
	for (int i = 0; i < m_fieldHeight; ++i)
		m_field[i].resize(m_fieldWidth);

	//game start
	StartNewGame();

	return true;
}

void Game::KeyDown(int key)
{

}

void Game::StartNewGame()
{
	for (int i = 0; i < m_fieldHeight; ++i)
	{
		for (int k = 0; k < m_fieldWidth; ++k)
		{
			m_field[i][k] = 0;
		}
	}

	m_state = RUNNING;
	m_currentLevel = 0;
	m_blockCount = 0;
	m_points = 0;
	SpawnBlock();
	m_block = m_nextBlock;
	m_nextBlock = NULL;
	SpawnBlock();
}

void Game::KeyUp(int key)
{
	if (key == DIK_M)
	{
		if(m_bMusic)
		{
			m_music->channel->stop();
			m_bMusic = false;
		}
		else
			m_bMusic = true;
	}
	if( m_state == RUNNING)
	{
		switch(key)
		{
		case DIK_DOWN:
			SendEvent(EVENT_MOVE_DOWN);
			break;

		case DIK_LEFT:
			SendEvent(EVENT_MOVE_LEFT);
			break;

		case DIK_RIGHT:
			SendEvent(EVENT_MOVE_RIGHT);
			break;

		case DIK_UP:
			SendEvent(EVENT_ROTATE);
			break;

		case DIK_SPACE:
			SendEvent(EVENT_JUMP_DOWN);
			break;
		}
	}
	else if (m_state == GAME_OVER)
	{
		switch(key)
		{
		case DIK_RETURN:
			StartNewGame();
			break;
		}
	}
}

void Game::Update(double deltaSecs)
{
	static int moveDir = 0;
	static bool down = false;
	static bool rotate = false;
	static double inputTime = 0;
	static double time = 0.0;

	m_input->Update();
	m_input->SendEvents(this);
	m_audio->Update();
	bool playing;
	m_music->channel->isPlaying(&playing);
	if(!playing &&m_bMusic)
	{
		m_audio->Play(m_music);
		m_music->channel->setVolume(0.2);
	}

	switch (m_state)
	{
		case RUNNING:
			ResetMovingParts();
			time += deltaSecs;
			if( time > m_levels[m_currentLevel].Speed)
			{
				if(!DropBlock())
				{
				}
				time = 0.0;
			}

			PrintBlock();
			TestRows();

			if (IsGameOver())
			{
				m_audio->Play(m_FXgameOver);
				m_state = GAME_OVER;
			}

			break;

		case DELETE_ROWS:
			AnimateRows(deltaSecs);
			
	}

	UpdateFrameRate(deltaSecs);
	
}

void Game::AnimateRows(double deltaSecs)
{
	static double animTime = 0;
	static int anim = 0;
	static int animCount = 0;
	animTime += deltaSecs;
	if (m_fullRows.empty())
	{
		animTime = 0;
		m_state = RUNNING;
	}
	else
	{
		if ( animTime > 0.05)
		{
			switch(anim)
			{
			case 2:
				for (int k = 0; k < m_fullRows.size(); ++k)
				{
					int row = m_fullRows[k];
					DeleteRow(row);
				}
				m_state = RUNNING;
				animCount = 0;
				anim = 0;
				break;

			case 1:
				for (int k = 0; k < m_fullRows.size(); ++k)
				{
					int row = m_fullRows[k];
					for (int i = 0; i < m_fieldWidth; ++i)
						m_field[row][i] = 2;
				}
				animCount++;
				anim = 0;
				break;

			case 0:
				for (int k = 0; k < m_fullRows.size(); ++k)
				{
					int row = m_fullRows[k];
					for (int i = 0; i < m_fieldWidth; ++i)
						m_field[row][i] = 0;
				}
				anim = 1;
			}
			animTime = 0;

			if(animCount > 5)
				anim = 2;
		}
	}
}

void Game::Render()
{
	HR(m_device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0));

	HR(m_device->BeginScene());

	HR(m_spriteHandler->Begin(D3DXSPRITE_ALPHABLEND));

	m_background->update(0.0);
	m_background->draw(m_spriteHandler);
	m_sprite->update(0.0);
	m_sprite->draw(m_spriteHandler);
	RenderField();
	RenderNextBlock();
	if (m_state == GAME_OVER)
	{
		m_gameOverLayer->update(0.0);
		m_gameOverLayer->draw(m_spriteHandler);
	}

	HR(m_spriteHandler->End());

	D3DCAPS9 caps;
	m_device->GetDeviceCaps(&caps);
	static char buffer[1028];
	sprintf_s(buffer, "Level = %u\n"
		"Points = %.0f\n", m_currentLevel, m_points);

	RECT R = {m_fieldPosition.x + m_fieldSize.x + 2 * m_cellWidth, SCREENHEIGHT - 4* m_cellHeight, 0, 0};
	HR(m_font->DrawText(0, buffer, -1, &R, DT_NOCLIP, D3DCOLOR_XRGB(0,0,0)));

	HR(m_device->EndScene());
	HR(m_device->Present(0, 0, 0, 0));
}

void Game::RenderField()
{
	for (int i = 0; i < m_fieldHeight; ++i)
	{
		for (int k = 0; k < m_fieldWidth; ++k)
		{
			if (m_field[i][k] == 1)
			{
				SpritePtr pSprite = m_images[m_block->ImageName];
				pSprite->setPosition(D3DXVECTOR3(m_fieldPosition.x + k*m_cellWidth, m_fieldPosition.y + i * m_cellHeight, 0));
				pSprite->update(0.0);
				pSprite->draw(m_spriteHandler);
			}
			else if (m_field[i][k] == 2)
			{
				m_inactiveSprite->setPosition(D3DXVECTOR3(m_fieldPosition.x + k*m_cellWidth, m_fieldPosition.y + i * m_cellHeight, 0));
				m_inactiveSprite->update(0.0);
				m_inactiveSprite->draw(m_spriteHandler);
			}
		}
	}
}

void Game::RenderNextBlock()
{
	for(int i = 0; i < m_nextBlock->Parts.size(); ++i)
	{
		int xpos = (m_fieldWidth + m_nextBlockPos.x + m_nextBlock->Parts[i].x) * m_cellWidth;
		int ypos = (m_nextBlockPos.y + m_nextBlock->Parts[i].y) * m_cellHeight;
		SpritePtr pSprite = m_images[m_nextBlock->ImageName];
		pSprite->setPosition(D3DXVECTOR3(xpos, ypos, 0));
		pSprite->update(0.0);
		pSprite->draw(m_spriteHandler);
	}
}

void Game::Close()
{
}

void Game::PrintBlock()
{
	for (int i = 0; i < m_block->Parts.size(); ++i)
	{
		int ypos = m_block->Position.y + m_block->Parts[i].y;
		int xpos = m_block->Position.x + m_block->Parts[i].x;

		m_field[ypos][xpos] = 1;
	}
}

void Game::ResetMovingParts()
{
		//reset moving parts on field
	for (int i = 0; i < m_fieldHeight; ++i)
	{
		for (int k = 0; k < m_fieldWidth; ++k)
		{
			if (m_field[i][k] == 1)
				m_field[i][k] = 0;
		}
	}
}

bool Game::DropBlock()
{
	bool possible = true;

	for (int i = 0; i < 4; ++i)
	{
		int ypos = m_block->Position.y + m_block->Parts[i].y;
		int xpos = m_block->Position.x + m_block->Parts[i].x;

		if (ypos+1 >= m_fieldHeight)
		{
			possible = false;
			break;
		}
		else if (m_field[ypos+1][xpos] == 2)
		{
			possible = false;
			break;
		}
	}

	if(possible)
	{
		m_block->Position.y += 1;
		return true;
	}

	for (int i = 0; i < m_block->Parts.size(); ++i)
	{
		int ypos = m_block->Position.y + m_block->Parts[i].y;
		int xpos = m_block->Position.x + m_block->Parts[i].x;

		m_field[ypos][xpos] = 2;
	}

	m_points += m_block->Parts.size() * m_levels[m_currentLevel].Factor;
	SAFE_DELETE(m_block);
	m_block = m_nextBlock;
	m_nextBlock = NULL;
	SpawnBlock();
	m_blockCount++;

	if (m_blockCount >= m_levels[m_currentLevel].Length)
	{
		m_blockCount = 0;
		if (m_currentLevel < m_levels.size() - 1)
		{
			m_currentLevel++;
			m_audio->Play(m_FXnewLevel);
		}
	}


	return false;
}

void Game::SpawnBlock()
{
	int random = rand() % m_blockTypes.size();

	m_nextBlock = new TetrisBlock();

	m_nextBlock->Height = m_blockTypes[random].Height;
	m_nextBlock->Width = m_blockTypes[random].Width;
	m_nextBlock->ImageName = m_blockTypes[random].ImageName;

	for (int i = 0; i < m_blockTypes[random].Parts.size(); ++i)
	{
		m_nextBlock->Parts.push_back(m_blockTypes[random].Parts[i]);
	}
	
	random = rand() % (m_fieldWidth - m_nextBlock->Width - 1);
	m_nextBlock->Position.x = random;
	m_nextBlock->Position.y = 0;
}

void Game::UpdateFrameRate(double deltaSecs)
{
	static double time = 0;
	time += deltaSecs;

	if (time > 1.0)
	{
		m_frameRate = 1.0/deltaSecs;
		time = 0;
	}
}

void Game::SendEvent(GameEvent gameEvent)
{
	switch(gameEvent)
	{
	case EVENT_MOVE_LEFT:
		MoveBlock(-1);
		break;
	case EVENT_MOVE_RIGHT:
		MoveBlock(1);
		break;
	case EVENT_MOVE_DOWN:
		if(!DropBlock())
		{
		}
		break;
	case EVENT_ROTATE:
		RotateBlock();
		break;

	case EVENT_JUMP_DOWN:
		while(DropBlock())
		{
			// nothing haha
		}
		m_audio->Play(m_FXjump);
	}
}

bool Game::MoveBlock(int dir)
{
	bool possible = true;

	for (int i = 0; i < m_block->Parts.size(); ++i)
	{
		int ypos = m_block->Position.y + m_block->Parts[i].y;
		int xpos = m_block->Position.x + m_block->Parts[i].x + dir;

		if (xpos > m_fieldWidth -1 || xpos < 0)
		{
			possible = false;
			break;
		}

		if (m_field[ypos][xpos] == 2)
		{
			possible = false;
			break;
		}
	}

	if(possible)
	{
		m_block->Position.x += dir;
		return true;
	}

	return false;
}

bool Game::RotateBlock()
{
	TetrisBlock testBlock;
	Vec2 newCorner(m_block->Width -1, 0);
	for (int i = 0; i < m_block->Parts.size(); ++i)
	{
		int ypos = newCorner.x - m_block->Parts[i].x;
		int xpos = m_block->Parts[i].y;

		if (xpos + m_block->Position.x > m_fieldWidth -1 || ypos + m_block->Position.y > m_fieldHeight -1
			|| xpos + m_block->Position.x < 0 || ypos + m_block->Position.y < 0)
			return false;

		if (m_field[ypos+ m_block->Position.y][xpos + m_block->Position.x] == 2)
			return false;
		
		testBlock.Parts.push_back(Vec2(xpos, ypos));
	}
	m_block->Parts = testBlock.Parts;
	m_block->Width = m_block->Height;
	m_block->Height = newCorner.x +1 ;
	m_audio->Play(m_FXrotate);

	return true;
}

void Game::TestRows()
{
	m_fullRows.clear();
	for (int i = 0 ; i < m_fieldHeight; ++i)
	{
		bool bIsFull = true;
		for (int k = 0; k < m_fieldWidth; ++k)
		{
			if (m_field[i][k] != 2)
			{
				bIsFull = false;
				break;
			}
		}

		if (bIsFull)
		{
			m_fullRows.push_back(i);
		}
	}
	if (!m_fullRows.empty())
	{
		m_points += m_fullRows.size() * m_fullRows.size() * m_fieldWidth * m_levels[m_currentLevel].Factor;
		m_state = DELETE_ROWS;
		m_audio->Play(m_FXdeleteLine);
	}
}

bool Game::IsGameOver()
{
	for (int i = 0; i < m_fieldWidth; ++i)
	{
		if (m_field[0][i] == 2)
			return true;
	}

	return false;
}

void Game::DeleteRow(int row)
{
	for (int i = row; i > 0; --i)
		for (int k = 0; k < m_fieldWidth; ++k)
			m_field[i][k] = m_field[i - 1][k];
}


bool Game::LoadGame(const char* filename)
{
	tinyxml2::XMLDocument doc;
	doc.LoadFile(filename);
	tinyxml2::XMLElement *pRoot = doc.RootElement();
	if(!pRoot)
		return false;

	pRoot->FirstChildElement("Field")->QueryIntAttribute("rows", &m_fieldHeight);
	pRoot->FirstChildElement("Field")->QueryIntAttribute("cols", &m_fieldWidth);
	pRoot->FirstChildElement("Field")->QueryIntAttribute("x", &m_fieldPosition.x);
	pRoot->FirstChildElement("Field")->QueryIntAttribute("y", &m_fieldPosition.y);
	pRoot->FirstChildElement("Field")->QueryIntAttribute("width", &m_fieldSize.x);
	pRoot->FirstChildElement("Field")->QueryIntAttribute("height", &m_fieldSize.y);

	pRoot->FirstChildElement("NextBlock")->QueryIntAttribute("x", &m_nextBlockPos.x);
	pRoot->FirstChildElement("NextBlock")->QueryIntAttribute("y", &m_nextBlockPos.y);

	pRoot->FirstChildElement("Window")->QueryIntAttribute("width", &SCREENWIDTH);
	pRoot->FirstChildElement("Window")->QueryIntAttribute("height", &SCREENHEIGHT);

	tinyxml2::XMLElement* pLevels = pRoot->FirstChildElement("Levels");
	for (tinyxml2::XMLElement* pNode = pLevels->FirstChildElement("Level"); pNode;
		pNode = pNode->NextSiblingElement("Level"))
	{
		GameLevel level;
		pNode->QueryIntAttribute("length", &level.Length);
		pNode->QueryDoubleAttribute("speed", &level.Speed);
		pNode->QueryDoubleAttribute("factor", &level.Factor);

		m_levels.push_back(level);
	}

	return true;
}

bool Game::LoadBlockTypes(const char* filename)
{
	tinyxml2::XMLDocument doc;
	doc.LoadFile(filename);
	tinyxml2::XMLElement *pRoot = doc.RootElement();
	if(!pRoot)
		return false;

	for (tinyxml2::XMLElement* pNode = pRoot->FirstChildElement("Block"); pNode;
		pNode = pNode->NextSiblingElement("Block"))
	{
		TetrisBlock block;
		block.Width = 0;
		block.Height = 0;

		for (tinyxml2::XMLElement* pElementNode = pNode->FirstChildElement("Element"); pElementNode;
			pElementNode = pElementNode->NextSiblingElement("Element"))
		{
			int xval, yval;
			pElementNode->QueryIntAttribute("x", &xval);
			pElementNode->QueryIntAttribute("y", &yval);
			block.Parts.push_back(Vec2(xval, yval));

			if (xval + 1 > block.Width)
				block.Width = xval +1;
			if (yval + 1 > block.Height)
				block.Height = yval +1;
		}

		tinyxml2::XMLElement* pImage = pNode->FirstChildElement("Image");
		std::string image = pImage->Attribute("name");

		if(m_images.find(image) == m_images.end())
		{
			SpritePtr pSprite(new CSprite());
			std::shared_ptr<CTexture> texture(new CTexture());
			if(!texture->Load("Media/"+image, m_device))
				return false;

			pSprite->setImage(texture);
			float xscale = (float)m_cellWidth/pSprite->getWidth();
			float yscale = (float)m_cellHeight/pSprite->getHeight();
			pSprite->setScale(D3DXVECTOR3(xscale, yscale, 0));

			m_images[image] = pSprite;
		}

		block.ImageName = image;
		m_blockTypes.push_back(block);
	}

	
	return true;
}

bool Game::InitD3D()
{
	D3DDEVTYPE devType = D3DDEVTYPE_HAL;
	DWORD requestedVP = D3DCREATE_HARDWARE_VERTEXPROCESSING;

	if(m_hWnd == NULL)
		return false;

	//Create IDirect3D9 Object
	m_d3d = Direct3DCreate9(D3D_SDK_VERSION);
	if (!m_d3d)
		return false;

	//Verify hardware support for specified formats in windowed and full screen modes
	D3DDISPLAYMODE mode;
	m_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode);
	HR(m_d3d->CheckDeviceType(D3DADAPTER_DEFAULT, devType, mode.Format, mode.Format, true));
	HR(m_d3d->CheckDeviceType(D3DADAPTER_DEFAULT, devType, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, false));

	//Check for requested vertex processing and pure device
	D3DCAPS9 caps;
	HR(m_d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, devType, &caps));

	DWORD devBehaviorFlags = 0;
	if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
		devBehaviorFlags |= requestedVP;
	else
		devBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	// If pure device and HW T&L supported
	if( caps.DevCaps & D3DDEVCAPS_PUREDEVICE &&
		devBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
			devBehaviorFlags |= D3DCREATE_PUREDEVICE;

		
	//Fill out the D3DPRESENT_PARAMETERS structure
	m_d3dpp.BackBufferWidth			   = SCREENWIDTH;
	m_d3dpp.BackBufferHeight		   = SCREENHEIGHT;
	if (FULLSCREEN)
		m_d3dpp.BackBufferFormat       = D3DFMT_X8R8G8B8;	
	else
		m_d3dpp.BackBufferFormat       = D3DFMT_UNKNOWN;
	m_d3dpp.BackBufferCount            = 1;
	m_d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
	m_d3dpp.MultiSampleQuality         = 0;
	m_d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
	m_d3dpp.hDeviceWindow              = m_hWnd;
	m_d3dpp.Windowed                   = (!FULLSCREEN);
	m_d3dpp.EnableAutoDepthStencil     = true; 
	m_d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
	m_d3dpp.Flags                      = 0;
	m_d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	m_d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

	//Create the device.
	HR(m_d3d->CreateDevice(
		D3DADAPTER_DEFAULT,			// primary adapter
		devType,					// device type
		m_hWnd,    // window associated with device
		devBehaviorFlags,			// vertex processing
		&m_d3dpp,						// present parameters
		&m_device));				 // return created device

	if(m_device == NULL)
		return false;

	//clear the backbuffer to black
	HR(m_device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xfff00fff, 1.0f, 0));
	
	//create pointer to the back buffer
	HR(m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_backbuffer));

	if (m_backbuffer == NULL)
		return false;

	//init 2D renderer
	HR(D3DXCreateSprite(m_device, &m_spriteHandler));

	if (m_spriteHandler == NULL)
		return false;

	return true;
}